using System.Collections;
using System.Collections.Generic;
using DG.Tweening;
using Framework;
using Unity.VisualScripting;
using UnityEngine;
namespace Food
{
    public class FoodManager : GameSingletonMonoBehaviour<FoodManager>
    {
        public int FoodNumber;
        /// <summary>
        /// 射出的起始点🤔(后面可能要改)
        /// </summary>
        [SerializeField]
        private GameObject ShootStartPointGameObject;
        /// <summary>
        /// 设计开始的坐标
        /// </summary>
        private Vector2 ShootStartPoint => ShootStartPointGameObject.transform.position;

        [SerializeField]
        [Header("射出的食物的预制体的对象池默认值")]
        private int ObjectNumber;
        /// <summary>
        /// 所发射食物的预制体
        /// </summary>
        [SerializeField] GameObject foodObjectPrefab;
        private Stack<FoodObject> foodObjectPool;//可能要射很多做个简单池
        /// <summary>
        /// 两个食物的射击间隔
        /// </summary>
        private float dataTime = 0.2f;
        /// <summary>
        /// 等待发射的食物队列
        /// </summary>
        private Queue<foodConsumeHelper> foodConsumeHelperQueue;
        private Queue<ConsumeFoodComponent> hungryDiePeople;
        /// <summary>
        /// 正在发射食物
        /// (因为食物在发射的时候不需要重复调用携程)
        /// </summary>
        private bool IsShooting;
        [SerializeField]
        private void Start()
        {
            foodObjectPool = new Stack<FoodObject>();
            foodConsumeHelperQueue = new Queue<foodConsumeHelper>();
            hungryDiePeople = new Queue<ConsumeFoodComponent>();
            for (int i = 0; i < ObjectNumber; i++)
            {
                FoodObject foodObject = CreateNewObject();
                foodObjectPool.Push(foodObject);
            }
        }
        #region 转变食物值
        public void AddFoodValue(CreateFoodComponent component)
        {

        }
        #endregion
        #region 消耗食物

        /// 消耗食物
        /// </summary>
        /// <param name="vector">卡片坐标用来实现把食物发射出去</param>
        /// <param name="consumeFoods">消耗的食物值</param>
        /// <returns>返回是否可以重新消耗</returns>
        public bool ConsumeFood(Vector2 vector, int consumeFoods, ConsumeFoodComponent component)
        {
            if (consumeFoods > FoodNumber)
            {
                //饿死的人在后面统一饿死
                hungryDiePeople.Enqueue(component);
                return false;
            }
            FoodNumber -= consumeFoods;
            foodConsumeHelper foodConsumeHelper = new foodConsumeHelper();
            foodConsumeHelper.CharacterPosition = vector;
            foodConsumeHelper.needFoodsNumber = consumeFoods;
            foodConsumeHelper.CharacterComponent = component;
            foodConsumeHelperQueue.Enqueue(foodConsumeHelper);
            if (!IsShooting)
            {
                StartCoroutine(ShootIE());
            }
            return true;
        }
        /// <summary>
        /// 发送消耗食物的信号
        /// </summary>
        public void ConsumeFoodSig()
        {
            SendSignal(SignalNameDef.CONSUME_FOOD, null);
        }

        #endregion
        #region 发射食物
        /// <summary>
        /// 把食物的物体射出去（
        /// </summary>
        /// <param name="vector"></param>
        private void Shoot(foodConsumeHelper consumeData)//把食物值射出去()
        {
            FoodObject foodObject;
            if (foodObjectPool.Count > 0)
            {
                foodObject = foodObjectPool.Pop();
            }
            else foodObject = CreateNewObject();
            foodObject.ShootTo(ShootStartPoint, consumeData.CharacterPosition, consumeData.CharacterComponent);
        }
        /// <summary>
        /// 创造食物物体实例
        /// </summary>
        /// <returns></returns>
        private FoodObject CreateNewObject()
        {
            FoodObject reFoodObject = new FoodObject();
            GameObject newObject = Instantiate(foodObjectPrefab, ShootStartPointGameObject.transform);
            reFoodObject.gameObject = newObject;
            return reFoodObject;
        }
        /// <summary>
        /// 把射出的小物体放回对象池
        /// </summary>
        /// <param name="food"></param>
        public bool PushFood(FoodObject food)
        {
            if (foodObjectPool.Count < ObjectNumber)
            {
                foodObjectPool.Push(food);
                return true;
            }
            return false;
        }
        /// <summary>
        /// 只是辅助存储信息的
        /// </summary>
        class foodConsumeHelper
        {
            public int needFoodsNumber;
            public Vector2 CharacterPosition;
            public ConsumeFoodComponent CharacterComponent;
        }
        /// <summary>
        /// 用携程是因为有间隔时间
        /// </summary>
        /// <returns></returns>
        IEnumerator ShootIE()
        {
            IsShooting = true;
            while (foodConsumeHelperQueue.Count > 0)
            {
                foodConsumeHelper helper = foodConsumeHelperQueue.Dequeue();
                for (int i = 0; i < helper.needFoodsNumber; i++)
                {
                    Shoot(helper);
                    yield return new WaitForSeconds(dataTime);
                }
            }
            while (hungryDiePeople.Count > 0)
            {
                ConsumeFoodComponent peopleDie = hungryDiePeople.Dequeue();
                peopleDie.HungryDie();
                yield return new WaitForSeconds(dataTime);
            }
            IsShooting = false;
            yield break;
        }
        #endregion
        #region 食物组件
        /// <summary>
        ///  表示饥饿的物体，在食物组件里自动生成(?) 
        /// </summary> 
        public GameObject HungryObject;
        #endregion

    }
    #region 射出的小食物
    /// <summary>
    /// 控制发射出去的小物体
    /// </summary>
    public class FoodObject
    {
        public GameObject gameObject;
        private Ease ease = Ease.InOutCubic;
        private float duringTime = 1;
        public void ShootTo(Vector2 startPoint, Vector2 endPoint, ConsumeFoodComponent characterComponent = null)
        {
            gameObject.transform.position = startPoint;
            Vector3[] vector2s = new Vector3[3];
            vector2s[0] = gameObject.transform.position;
            vector2s[1] = (endPoint + startPoint) / 2 + Vector2.one * Random.Range(-1f, 1f);//暂定
            vector2s[2] = endPoint;
            gameObject.SetActive(true);
            gameObject.transform.DOPath(vector2s, duringTime, PathType.CatmullRom).SetEase(ease).OnComplete(() =>
            {
                if (characterComponent != null)
                {
                    characterComponent.FinishEat();
                }
                DeleteAnimation();
            });
        }
        public void Delete()
        {
            if (FoodManager.Instance.PushFood(this))
            {
                gameObject.SetActive(false);
            }
            else
            {
                GameObject.Destroy(gameObject);
            }
        }
        public void DeleteAnimation()
        {
            gameObject.transform.DOShakePosition(duringTime / 10, 0.2f).OnComplete(() =>
            {
                Delete();
            });
        }

    }
    #endregion

}
